package com.zsqr.dashboard.controller;

import java.nio.charset.Charset;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;


import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.zsqr.dashboard.domain.*;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType;
import org.apache.http.client.methods.HttpUriRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
//import org.springframework.http.converter.;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.HttpMessageConverterExtractor;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletResponse;
//import net.sourceforge.tess4j.Tesseract;
/**
 * REST service client
 */
@Controller
@RequestMapping("/client")
public class RestClientController {

	protected static Logger logger = Logger.getLogger("controller");
	
	private RestTemplate restTemplate = new RestTemplate();
	//Tesseract instance = Tesseract.getInstance();
	
	/**
	 * Retrieves list of cards 
	 */
	@RequestMapping(value = "/getcard", method = RequestMethod.GET)
	public String getCards(@RequestParam("username") String username, Model model) {
		logger.debug("Retrieve all card list");
		
		// Prepare acceptable media type
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		acceptableMediaTypes.add(MediaType.APPLICATION_XML);
		
		// Prepare header
		HttpHeaders headers = new HttpHeaders();
		headers.setAccept(acceptableMediaTypes);
		HttpEntity<UserCardEntity> entity = new HttpEntity<UserCardEntity>(headers);

		// Send the request as GET
		try {
			ResponseEntity<UserCardList> cardList = restTemplate.exchange("http://localhost:8081/zsqr/app/user/cardlist/{username}", 
					HttpMethod.GET,entity , UserCardList.class,username);
			// Add to model
			model.addAttribute("cardlist", cardList.getBody().getCardInfo());
			
			
		} catch (Exception e) {
			logger.error(e);
		}
		
				
		// If need to return data in UI page
		// This will resolve to /WEB-INF/flows/main/welcome.xhtml
		return "welcome";
	}
	
	/**
	 * Retrieves a single user record from the REST provider
	 * http://localhost:8081/zsqr/app/client/get/test@test.com
	 * For integration we remove request mapping and we will call method getUser(String username)
	 */
	@RequestMapping(value = "get/{username:.+}", method = RequestMethod.GET)
	public void getUser(@PathVariable("username") String username) {
		logger.debug("Retrieve User with id: " + username);
		String uname = null;
		// Prepare acceptable media type
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		acceptableMediaTypes.add(MediaType.APPLICATION_XML);
		
		// Prepare header
		HttpHeaders headers = new HttpHeaders();
		headers.setAccept(acceptableMediaTypes);
		HttpEntity<UserEntity> entity = new HttpEntity<UserEntity>(headers);

		// Send the request as GET
		try {
			ResponseEntity<UserEntity> result = restTemplate.exchange("http://localhost:8081/zsqr/app/user/loaduser/{username}",
					HttpMethod.GET, entity, UserEntity.class, username);
			// Add to model
			uname = result.getBody().getUserName();
			System.out.println("user name is : " + result.getBody().getFirstName()
					+ " for user ID : " + uname);
			
			//model.addAttribute("user", result.getBody());
			
		} catch (Exception e) {
			logger.error(e);
		}
		
		
		// If need to return data in UI page
		// This will resolve to /WEB-INF/welcome.xhtml
		//return uname;
	}
	
	/**
	 * Retrieves Credit Sell response from X-Charge
	 * http://localhost:8081/zsqr/app/client/get/creditsaleresponse/ 
	 */
	@RequestMapping(value = "get/creditsaleresponse/", method = RequestMethod.POST)
	@ResponseBody public CreditSaleResponse getGatewayResponse(@RequestBody CreditSaleRequest creditSaleRequest) {
		logger.debug("Retrieve User with id: ");
		String uname = null;
		// Prepare acceptable media type
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		//acceptableMediaTypes.add(MediaType.APPLICATION_XML);
	    //acceptableMediaTypes.add(MediaType.TEXT_XML);
		//acceptableMediaTypes.add(MediaType.TEXT_PLAIN);
		acceptableMediaTypes.add(MediaType.ALL);
		
		List<Charset> acceptableCharsets  = new ArrayList<Charset>(Charset.availableCharsets().values());
		
		
	
		// Prepare header
		
		HttpHeaders headers = new HttpHeaders();
		headers.setAccept(acceptableMediaTypes);
		//headers.setAcceptCharset(acceptableCharsets);
		headers.setContentType(MediaType.TEXT_XML);
		headers.setContentLength(8092);
		//headers.setContentType(MediaType.TEXT_XML);
		
		HttpEntity<CreditSaleRequest>entity = new HttpEntity<CreditSaleRequest>(creditSaleRequest,headers);
		

				
		// Send the request as GET
		try {
			
	
			HttpEntity<String>  result = restTemplate.exchange("https://test.t3secure.net/x-chargeweb.dll",
					HttpMethod.POST, entity, String.class);
			
			String screditResponse =  result.getBody();
			JAXBContext jaxb = JAXBContext.newInstance(CreditSaleResponse.class);
			Unmarshaller u = jaxb.createUnmarshaller();
			//publicKeyResponse = (GatewayResponse)u.unmarshal( ClassLoader.getSystemResourceAsStream(sPublicResponse));
			StreamSource streamSource = new StreamSource(new StringReader(screditResponse)) ;
			JAXBElement<CreditSaleResponse> je = u.unmarshal(streamSource, CreditSaleResponse.class);
	       
			CreditSaleResponse creditSaleResponse = (CreditSaleResponse)je.getValue(); 
	        System.out.println(creditSaleResponse);
			return creditSaleResponse;
			//return gatewayResp;
			//model.addAttribute("user", result.getBody());
			
		} catch (Exception e) {
			logger.error(e);
			return null;
		}
		
		
		// If need to return data in UI page
		// This will resolve to /WEB-INF/welcome.xhtml
		//return uname;
	}
	
	
	/**
	 * Retrieves publicKeyResponse from X-Charge
	 * http://localhost:8081/zsqr/app/client/get/publicKeyResponse/
	 * 
	 */
	@RequestMapping(value = "get/publicKeyResponse/", method = RequestMethod.POST)
	@ResponseBody public GatewayResponse getPublicKeyResponse(@RequestBody GatewayRequest gatewayRequest) {
		logger.debug("Retrieve User with id: ");
		String uname = null;
		// Prepare acceptable media type
		List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
		//acceptableMediaTypes.add(MediaType.APPLICATION_XML);
	    //acceptableMediaTypes.add(MediaType.TEXT_XML);
		//acceptableMediaTypes.add(MediaType.TEXT_PLAIN);
		acceptableMediaTypes.add(MediaType.ALL);
		 
		//final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
		List<Charset> acceptableCharsets  = new ArrayList<Charset>(Charset.availableCharsets().values());
		//List<Charset> acceptableCharsets  = new ArrayList<Charset>();
		
	
		// Prepare header
		//HttpMessageConverter bufferedIamageHttpMessageConverter =   new ByteArrayHttpMessageConverter();
		HttpHeaders headers = new HttpHeaders();
		//headers.set("Content-Type", "multipart/form-data"); // we are sending a form
		//headers.set("Accept", "text/plain"); // looks like you want a string back
		headers.setAccept(acceptableMediaTypes);
		//acceptableCharsets.add(Charset.forName("iso-8859-1"));
		//headers.setAcceptCharset(acceptableCharsets);
	//	headers.setContentType(MediaType.APPLICATION_XML);
		headers.setContentType(MediaType.TEXT_XML);
		headers.setContentLength(8092);
		
		//GatewayRequest gatewayRequest = new GatewayRequest();
		
		//headers.add("Cookie", "JSESSIONID=" + session.getValue());
		
		HttpEntity<GatewayRequest>entity = new HttpEntity<GatewayRequest>(gatewayRequest,headers);
		//CreditSaleResponse PublicKeyResponse = new CreditSaleResponse();

		//HttpRequest host = new HttpRequest("localhost", 8080, "http");
       // restTemplate1 = new RestTemplate1(new HttpComponentsClientHttpRequestFactory(host));
		//ArrayList<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
		List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
		messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
		messageConverters.add(new StringHttpMessageConverter());
		//SimpleXmlHttpMessageConverter  simplemsg = new SimpleXmlHttpMessageConverter();
		//restTemplate.setMessageConverters(messageConverters);
		//Jaxb2RootElementHttpMessageConverter jaxb1 = new Jaxb2RootElementHttpMessageConverter();
		//jaxb1.
		ByteArrayHttpMessageConverter converter = new ByteArrayHttpMessageConverter();
		//converter.setSupportedMediaTypes(Arrays.asList(new MediaType("*", "*")));
	    messageConverters.add(converter);

		

	
		
		//List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
		//MappingJacksonHttpMessageConverter map = new MappingJacksonHttpMessageConverter();
		//messageConverters.add(map);
		//restTemplate.setMessageConverters(messageConverters);
//*****
		  // HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
           //RestTemplate restTemplate = new RestTemplate(requestFactory);

		//<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
		//messageConverters.add(new FormHttpMessageConverter());
		//messageConverters.add(new StringHttpMessageConverter());

		StringHttpMessageConverter xmlMessageConverter = new StringHttpMessageConverter();
		
		//ArrayList supportedMediaTypes = new ArrayList();

	   // MediaType mediaType = new MediaType("text", "plain", Charset.forName("ISO-8859-1"));
	    //acceptableMediaTypes.add(mediaType); 
		//xmlMessageConverter.setSupportedMediaTypes(acceptableMediaTypes);
		
		//xmlMessageConverter.setWriteAcceptCharset(true);
		//messageConverters.add(bufferedIamageHttpMessageConverter);
		
		//restTemplate.setMessageConverters(messageConverters);

		

		
//***
		
		// Send the request as GET
		try {
			
	
			HttpEntity<String>  result = restTemplate.exchange("https://test.t3secure.net/x-chargeweb.dll",
					HttpMethod.POST, entity, String.class);
			//GatewayResponse  gatewayResp  = restTemplate.postForObject("https://test.t3secure.net/x-chargeweb.dll",
					// entity, GatewayResponse.class);
			// Add to model
		//	uname = result.getBody();
			//System.out.println("user name is : " + result.getBody().getAcctNumSource()
				//	+ " for user ID : " );
			
			//GatewayResponse publicKeyResponse =  result.getBody();
			GatewayResponse publicKeyResponse =  new GatewayResponse();
			String sPublicResponse=result.getBody();
			//Jaxb2RootElementHttpMessageConverter jaxb = new Jaxb2RootElementHttpMessageConverter();
			//publicKeyResponse = jaxb.read(GatewayResponse.class, result.getBody());
			//convertStringToObject(String,)
			JAXBContext jaxb = JAXBContext.newInstance(GatewayResponse.class);
			Unmarshaller u = jaxb.createUnmarshaller();
			//publicKeyResponse = (GatewayResponse)u.unmarshal( ClassLoader.getSystemResourceAsStream(sPublicResponse));
			StreamSource streamSource = new StreamSource(new StringReader(sPublicResponse)) ;
			JAXBElement<GatewayResponse> je = u.unmarshal(streamSource, GatewayResponse.class);
	       
	        publicKeyResponse = (GatewayResponse)je.getValue(); 
	        System.out.println(publicKeyResponse);
	        //PojoXml pojoXml = PojoXmlFactory.createPojoXml();
			return publicKeyResponse;
			
			//return gatewayRequest;
			//return gatewayResp;
			//model.addAttribute("user", result.getBody());
			
		} catch (Exception e) {
			logger.error(e);
			return null;
		}
		
		
		// If need to return data in UI page
		// This will resolve to /WEB-INF/welcome.xhtml
		//return uname;
	}
	
}